"""
Adaptive solver implementations
"""

"""
    AdaptiveSolver <: AbstractSolver

Adaptive time stepping using DifferentialEquations.jl
"""
struct AdaptiveSolver <: AbstractSolver
    alg::Any
    rtol::Float64
    abstol::Float64
    kwargs::Dict{Symbol, Any}
    
    function AdaptiveSolver(; alg=Tsit5(), rtol=1e-6, abstol=1e-8, kwargs...)
        new(alg, rtol, abstol, Dict(kwargs))
    end
end

function solve_pde(solver::AdaptiveSolver, pde::AbstractPDE, initial_state, t_span, tracker, storage; kwargs...)
    if isa(t_span, Number)
        t_span = (0.0, t_span)
    end
    
    # Convert field to vector form
    u0 = vec(data(initial_state))
    
    # Define ODE function
    function ode_func(u, p, t)
        # Convert back to field
        field_data = reshape(u, size(initial_state))
        field = ScalarField(field_data, grid(initial_state))
        
        # Compute evolution rate
        rate_field = evolution_rate(pde, field, t)
        
        return vec(data(rate_field))
    end
    
    # Create ODE problem
    prob = ODEProblem(ode_func, u0, t_span)
    
    # Solve
    sol = solve(prob, solver.alg; reltol=solver.rtol, abstol=solver.abstol, solver.kwargs...)
    
    # Convert final solution back to field
    final_data = reshape(sol.u[end], size(initial_state))
    return ScalarField(final_data, grid(initial_state))
end